package com.zyq.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zyq.common.entity.AclPermission;
import com.zyq.common.entity.AclRolePermission;
import com.zyq.security.utils.WebUtils;
import com.zyq.system.dao.AclPermissionDao;
import com.zyq.system.dao.AclRolePermissionDao;
import com.zyq.system.service.AclPermissionService;
import com.zyq.common.util.JWTUtil;
import com.zyq.common.vo.Result;
import com.zyq.system.service.AclRolePermissionService;
import com.zyq.system.vo.FenRolePermissionVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class AclPermissionServiceImpl implements AclPermissionService {
    @Autowired
    private AclPermissionDao aclPermissionDao;
    @Autowired
    private AclRolePermissionDao aclRolePermissionDao;
    @Autowired
    private AclRolePermissionService aclRolePermissionService;
    @Override
    public Result<Map<String, Object>> findPermissionByRoleId(String roleId) {
        // 1. 查询出来所有的权限信息
        List<AclPermission> permissions = aclPermissionDao.selectList(null);
        // 1.1 将权限信息进行分级管理   先将一级菜单提取出来
        List<AclPermission> first = new ArrayList<>();

        for (AclPermission permission : permissions) {
            if(permission.getPid().equals("1")){
                first.add(permission);
            }
        }

        for (AclPermission aclPermission : first) {
            aclPermission.setChildren(findChildren(permissions,aclPermission.getId()));
        }
        // 2. 通过角色id查询出来这个角色所具有的的权限
        QueryWrapper<AclRolePermission> aclRolePermissionQueryWrapper = new QueryWrapper<>();
        aclRolePermissionQueryWrapper.eq("role_id",roleId);
        List<AclRolePermission> aclRolePermissions = aclRolePermissionDao.selectList(aclRolePermissionQueryWrapper);

        List<String> collect = aclRolePermissions.stream().map(item -> item.getPermissionId()).collect(Collectors.toList());

        // 存放起来返回前端
        HashMap<String, Object> map = new HashMap<>();
        map.put("allPermissions",first);
        map.put("checkItems",collect);
        return new Result<>(2000,"角色权限查询成功",map);
    }

    @Override
    public Result<String> confirmFenPermission(FenRolePermissionVo fenRolePermissionVo) {
        // 1. 现将原先角色对应的权限  批量删除
        UpdateWrapper<AclRolePermission> aclRolePermissionUpdateWrapper = new UpdateWrapper<>();
        aclRolePermissionUpdateWrapper.eq("role_id",fenRolePermissionVo.getRoleId());
        aclRolePermissionService.remove(aclRolePermissionUpdateWrapper);
        // 2. 给角色赋予新的角色信息
        ArrayList<AclRolePermission> aclRolePermissions = new ArrayList<>();

        for (String permissionId : fenRolePermissionVo.getPermissionIds()) {
            AclRolePermission aclRolePermission = new AclRolePermission();
            aclRolePermission.setRoleId(fenRolePermissionVo.getRoleId());
            aclRolePermission.setPermissionId(permissionId);
            aclRolePermission.setIsDeleted(0);
            aclRolePermission.setGmtCreate(LocalDateTime.now());
            aclRolePermission.setGmtModified(LocalDateTime.now());
            aclRolePermissions.add(aclRolePermission);
        }

        boolean b = aclRolePermissionService.saveBatch(aclRolePermissions);
        if(b){
            return new Result<>(2000,"修改角色成功",null);
        }

        return new Result<>(5000,"修改角色权限失败",null);
    }

    private List<AclPermission> findChildren(List<AclPermission> permissions , String id){
        // 子菜单
        List<AclPermission> second = new ArrayList<>();

        for (AclPermission permission : permissions) {
            if(permission.getPid().equals(id)){
                second.add(permission);
            }
        }

        for (AclPermission aclPermission : second) {
            aclPermission.setChildren(findChildren(permissions,aclPermission.getId()));
        }
        return second;
    }
    @Override
    public Result<List<AclPermission>> getPermissionMenu() {
        // 1. 调用dao层方法，获取到全部符合条件的权限 ， 时候先需要从前端传过来的token里面获取到用户名信息，才能查询
        String token = WebUtils.getRequest().getHeader("token");
        // 2. 获取到token之后再，用封装的JWT工具类，来解析出来数据
        Map<String, Object> tokenChaim = JWTUtil.getTokenChaim(token);
        // 3. 从获取的数据当中获取到用户名
        String username = tokenChaim.get("username").toString();
        // 4. 调用dao层方法，从数据库里面获取到数据信息
        List<AclPermission> permissions = aclPermissionDao.getPermissionMenuByUsername(username);
        // 5. 用逻辑的手段将子菜单放在父菜单的下面   使用 方法递归的方式进行排列菜单，（因为可以存在多级菜单，递归很不错的吧）
        // 5.1 先将顶级父菜单从全部权限当中过滤出来
        ArrayList<AclPermission> first = new ArrayList<>();
        for (AclPermission permission : permissions) {
            if(permission.getPid().equals("1")){
                first.add(permission);
            }
        }
        // 5.2 将顶级菜单存放到了first里面，然后通过方法递归给这些父菜单添加上子菜单
        for (AclPermission firstPermission : first) {
            firstPermission.setChildren(addGetChildren(permissions,firstPermission.getId()));
        }

        return new Result<>(200,"菜单成功分好",first);
    }
    // 全部权限  和  要添加子菜单的父菜单的pid  进行匹配
    private List<AclPermission> addGetChildren(List<AclPermission> permissions,String id){
        // 收集子菜单
        ArrayList<AclPermission> second = new ArrayList<>();
        // 再次过滤出来子菜单
        for (AclPermission permission : permissions) {
            if(permission.getPid().equals(id)){
                second.add(permission);
            }
        }
        // 如果还存在三级菜单
        for (AclPermission aclPermission : second) {
            aclPermission.setChildren(addGetChildren(permissions,aclPermission.getId()));
        }
        return second;
    }

    @Override
    public Result<List<AclPermission>> getUserPermission(String id) {
        List<AclPermission> userPermissionByUserId = aclPermissionDao.getUserPermissionByUserId(id);
        if(userPermissionByUserId != null){
            return new Result<List<AclPermission>>(200,"查询权限成功",userPermissionByUserId);
        }
        return new Result<List<AclPermission>>(500, "用户信息查询失败", null);
    }
}
